package edu.tongji.gridding.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import edu.tongji.gridding.database.DocumentIndexDao;
import edu.tongji.gridding.database.TitleIndexDao;
import edu.tongji.gridding.datamodel.Response;
import edu.tongji.gridding.datamodel.Result;

public class QueryManager {
	private ThreadPoolExecutor threadPool;
	
	private DocumentIndexDao documentIndexDao;
	private TitleIndexDao titleIndexDao;
	
	public QueryManager(DocumentIndexDao documentIndexDao, TitleIndexDao titleIndexDao) {
		this.documentIndexDao = documentIndexDao;
		this.titleIndexDao = titleIndexDao;
		threadPool = new ThreadPoolExecutor(16, 100, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
	}
	
	public void init() {
		threadPool = new ThreadPoolExecutor(16, 100, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
	}
	
	public List<Result> queryDocuments(String[] keywords) throws InterruptedException {
		int threadCnt = keywords.length;
		CountDownLatch CDL = new CountDownLatch(threadCnt);
		
		List<Result> results = new ArrayList<Result>();
		for (int i = 0; i < threadCnt; i++) {
			DocumentQueryThread dThread = new DocumentQueryThread(documentIndexDao, keywords[i], -1, CDL, results);
			threadPool.execute(dThread);
		}
		
		CDL.await(60, TimeUnit.SECONDS);
		return results;
	}
	
	public Result queryDocument(String keyword) {
		Result result = new Result();
		List<String> l = documentIndexDao.queryDocument(keyword, -1);
		result.setKeyword(keyword);
		result.setReulsts(l);
		result.setCnt(l.size());
		return result;
	}
	
	public List<Result> queryTitles(String[] keywords) throws InterruptedException {
		int threadCnt = keywords.length;
		CountDownLatch CDL = new CountDownLatch(threadCnt);
		
		List<Result> results = new ArrayList<Result>();
		for (int i = 0; i < threadCnt; i++) {
			TitleQueryThread tThread = new TitleQueryThread(titleIndexDao, keywords[i], -1, CDL, results);
			threadPool.execute(tThread);
		}
		
		CDL.await(60, TimeUnit.SECONDS);
		return results;
	}
	
	public Result queryTitle(String keyword) {
		Result result = new Result();
		List<String> l = titleIndexDao.queryTitle(keyword, -1);
		result.setKeyword(keyword);
		result.setReulsts(l);
		result.setCnt(l.size());
		return result;
	}
	
	
	public Response queryDocAndTitle(String[] keywords) throws InterruptedException {
		Response response = new Response();
		CountDownLatch CDL = new CountDownLatch(2);
		
		TaskThread dThread = new TaskThread(this, "queryDocuments", keywords, response, "setDocQueryResults", CDL);
		threadPool.execute(dThread);
		TaskThread tThread = new TaskThread(this, "queryTitles", keywords, response, "setTitleQueryResults", CDL);
		threadPool.execute(tThread);
		
		CDL.await(60, TimeUnit.SECONDS);
		return response;
	}
	
	
	/**
	 *  Destruct function to release all threads
	 */
	public void release() {
		threadPool.shutdown();
	}

}
